package cn.hl.service.impl;

import cn.hl.constant.ImmutableStock;
import cn.hl.domain.*;
import cn.hl.dto.StockDto;
import cn.hl.enums.GlobalExceptionCode;
import cn.hl.exception.GlobalCustomException;
import cn.hl.feign.ProductService;
import cn.hl.feign.PurchaseService;
import cn.hl.mapper.StockMapper;
import cn.hl.properties.VariableStock;
import cn.hl.result.JSONResult;
import cn.hl.service.IStockLogService;
import cn.hl.service.IStockService;
import cn.hl.service.IStockWarningLogService;
import cn.hl.util.AssertUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hulan
 * @since 2022-09-29
 */
@Service
public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements IStockService {

    @Autowired
    private VariableStock variableStock;

    @Autowired
    private ProductService productService;

    @Autowired
    private IStockLogService stockLogService;

    @Autowired
    private IStockWarningLogService stockWarningLogService;

    @Autowired
    private PurchaseService purchaseService;

    /**
     * 出入库
     * @param stockDto
     */
    @Override
    public void inboundAndOutbound(StockDto stockDto) {
        Long productId = stockDto.getProductId();
        Integer count = stockDto.getCount();
        Integer status = stockDto.getStatus();
        Product product = getProduct(productId);
        String productName = product.getProductName();
        Long typeId = product.getTypeId();
        Stock stock = getStockByProductId(productId);
        if (status == variableStock.getInbound()) {
            if (stock == null) {
                saveStock(productId,productName,typeId,count);
            } else {
                stock.setCount(stock.getCount() + count);
                updateById(stock);
            }
            saveStockLog(productId,status,count,productName,typeId);
        } else if (status == variableStock.getOutbound()) {
            if (stock.getCount() < count) {
                if (stock.getCount() < variableStock.getThreshold()) {
                    saveStockWarningLog(stock.getCount(),productId,productName);
                    savePurchaseApply(productId,productName);
                }
                throw new GlobalCustomException(GlobalExceptionCode.OUT_OF_STOCK_ERROR);
            } else {
                stock.setCount(stock.getCount() - count);
                updateById(stock);
                saveStockLog(productId,status,count,productName,typeId);
            }
        }
    }

    private Stock getStockByProductId(Long productId) {
        Wrapper<Stock> wrapper = new EntityWrapper<>();
        wrapper.eq("product_id",productId);
        return selectOne(wrapper);
    }

    /**
     * 查询所有缺货的库存
     * @return
     */
    @Override
    public List<Stock> findOutOfStock() {
        Wrapper<Stock> wrapper = new EntityWrapper<>();
        wrapper.lt("count",variableStock.getThreshold());
        return selectList(wrapper);
    }

    private void saveStockLog(Long productId, Integer status, Integer count, String productName, Long typeId) {
        StockLog stockLog = new StockLog();
        stockLog.setProductId(productId);
        stockLog.setProductName(productName);
        stockLog.setTypeId(typeId);
        stockLog.setCount(count);
        stockLog.setStatus(status);
        stockLog.setCreateTime(new Date());
        stockLogService.insert(stockLog);
    }

    private void savePurchaseApply(Long productId, String productName) {
        PurchaseApply purchaseApply = new PurchaseApply();
        purchaseApply.setStatus(ImmutableStock.AUDIT);
        purchaseApply.setCount(variableStock.getPurchase_quantity_standard());
        purchaseApply.setCreateTime(new Date());
        purchaseApply.setProductId(productId);
        purchaseApply.setProductName(productName);
        purchaseService.saveOrUpdate(purchaseApply);
    }

    private void saveStock(Long productId, String productName, Long typeId, Integer count) {
        Stock stock = new Stock();
        stock.setProductId(productId);
        stock.setProductName(productName);
        stock.setTypeId(typeId);
        stock.setCount(count);
        stock.setCreateTime(new Date());
        insert(stock);
    }

    private void saveStockWarningLog(Integer count, Long productId,String productName) {
        StockWarningLog stockWarningLog = new StockWarningLog();
        stockWarningLog.setCreateTime(new Date());
        stockWarningLog.setCurrentCount(count);
        stockWarningLog.setInfo(ImmutableStock.INFO);
        stockWarningLog.setProductId(productId);
        stockWarningLog.setProductName(productName);
        stockWarningLogService.insert(stockWarningLog);
    }

    private Product getProduct(Long productId) {
        JSONResult jsonResult = productService.get(productId);
        AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionCode.FAIL);
        Product product = JSONObject.parseObject(JSONObject.toJSONString(jsonResult.getData()),Product.class);
        AssertUtil.isNotNull(product,GlobalExceptionCode.FAIL);
        return product;
    }

}
